/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "commonheaders.h"

INT GetContactInfo(WPARAM wParam, LPARAM lParam);

namespace NServices {
namespace NViewHomepage {

static HANDLE nhMenuItem		= NULL;
static HANDLE nhExtraIcon		= INVALID_HANDLE_VALUE;

/**
 * name:	DBGetHomepage
 * desc:	returns the email address of the contact
 * params:	hContact	- handle to contact to read email from
 *			dbv			- retrieves the email address string
 * return:	0 if email was found, 1 otherwise
 **/
static LPSTR DBGetHomepage(HANDLE hContact)
{
	// ignore owner
	if(hContact != NULL) {
		CONTACTINFO ci;

		ci.cbSize = sizeof(CONTACTINFO);
		ci.hContact = hContact;
		ci.szProto = NULL;
		ci.dwFlag = CNF_HOMEPAGE;
		ci.bVal = 0;

		if(GetContactInfo(NULL, (LPARAM)&ci)) {
			ci.dwFlag = CNF_COHOMEPAGE;
			if(GetContactInfo(NULL, (LPARAM)&ci))
				return NULL;
		}
		return (LPSTR)ci.pszVal;
	}
	return NULL;
}

/**
 * name:	MenuCommand
 * desc:	service function that sends emails
 * params:	wParam	- handle to contact to send an email to
 *			lParam	- not used
 * return:	0 if email was sent, 1 if not
 **/
static INT MenuCommand(WPARAM wParam,LPARAM lParam)
{
	LPSTR szUrl = DBGetHomepage((HANDLE)wParam);

	if(szUrl) {
		CallService(MS_UTILS_OPENURL, 1, (LPARAM)szUrl);
		mir_free(szUrl);
	}
	else
		MessageBox((HWND)lParam, 
			TranslateT("User has no valid homepage"),
			TranslateT("View Homepage"), MB_OK);
	return 0;
}

/***********************************************************************************************************
 * Event Handler functions
 ***********************************************************************************************************/

static INT OnCListRebuildIcons(WPARAM wParam, LPARAM lParam)
{
	nhExtraIcon = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)NIcoLib::GetIcon(ICO_BTN_GOTO), 0);;
	return 0;
}

/**
 * name:	OnCListApplyIcons
 * desc:	notification handler for clist extra icons to be applied for a contact
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
static INT OnCListApplyIcons(WPARAM wParam, LPARAM lParam)
{
	IconExtraColumn iec;
	LPSTR szUrl;

	iec.cbSize = sizeof(IconExtraColumn);
	// to support the ugly shitfuckin' clist_nicer++
	iec.ColumnType = myGlobals.IsCListNicer ? 1 : EXTRA_ICON_WEB;
	
	szUrl = DBGetHomepage((HANDLE)wParam);
	if(szUrl) {
		iec.hImage = nhExtraIcon;
		MIR_FREE(szUrl);
	}
	else
		iec.hImage = INVALID_HANDLE_VALUE;

	CallService(MS_CLIST_EXTRA_SET_ICON, wParam, (LPARAM)&iec);
	return 0;
}

/**
 * name:	OnContactSettingChanged
 * desc:	Notification handler for changed contact settings
 * param:	wParam	-	(HANDLE)hContact
 *			lParam	-	(DBCONTACTWRITESETTING*)pdbcws
 * return:	0 if setting was handled or 1 if not
 **/
static INT OnContactSettingChanged(WPARAM wParam, LPARAM lParam)
{
	DBCONTACTWRITESETTING* pdbcws = (DBCONTACTWRITESETTING*)lParam;
	
	if(!_strnicmp(pdbcws->szSetting, SET_CONTACT_HOMEPAGE, 8)) {
		OnCListApplyIcons(wParam, 0);
	}
	return 0;
}

/**
 * name:	OnPreBuildMenu
 * desc:	decides whether to show menuitem for sending emails or not
 * params:	wParam	- handle to contact to send an email to
 *			lParam	- not used
 * return:	0
 **/
static INT OnPreBuildMenu(WPARAM wParam, LPARAM lParam)
{
	LPSTR szUrl;
	CLISTMENUITEM mi;
	
	ZeroMemory(&mi,sizeof(mi));
	mi.cbSize = sizeof(mi);
	mi.flags = CMIM_FLAGS;

	szUrl = DBGetHomepage((HANDLE)wParam);
	if(szUrl) MIR_FREE(szUrl)
	else mi.flags = CMIM_FLAGS | CMIF_HIDDEN;

	CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)nhMenuItem, (LPARAM)&mi);
	return 0;
}

/***********************************************************************************************************
 * public Module Interface functions
 ***********************************************************************************************************/

/**
 * name:	RebuildMenu
 * desc:	enable or disable menuitem
 * params:	not used
 * return:	nothing
 **/
VOID RebuildMenu()
{
	static HANDLE hPrebuildMenuHook = NULL;

	if(DBGetByte(SET_GETCONTACTINFO_ENABLED, DEFVAL_GETCONTACTINFO_ENABLED)) {

		if(!hPrebuildMenuHook)
			hPrebuildMenuHook = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnPreBuildMenu);

		if(!nhMenuItem) {
			CLISTMENUITEM mi;

			// insert contact menuitem
			ZeroMemory(&mi, sizeof(mi));
			mi.cbSize = sizeof(mi);
			mi.position = -2000010000;
			mi.hIcon = NIcoLib::GetIcon(ICO_BTN_GOTO);
			mi.pszName = "&Homepage";
			mi.pszService = MS_USERINFO_HOMEPAGE_OPENURL;
			nhMenuItem = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi);
		}
	}
	else {
		if(nhMenuItem && !CallService(MS_CLIST_REMOVECONTACTMENUITEM, (WPARAM)nhMenuItem, NULL)) {
			nhMenuItem = NULL;
			if(hPrebuildMenuHook) {
				UnhookEvent(hPrebuildMenuHook);
				hPrebuildMenuHook = NULL;
			}
		}
	}
}

/**
 * name:	ApplyCListIcons
 * desc:	force all icons to be reloaded
 * param:	wParam	- handle to the contact whose extra icon is to apply
 *			lParam	- not used
 **/
VOID ApplyCListIcons()
{
	WPARAM wContact;

	//walk through all the contacts stored in the DB
	for(wContact = CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
		wContact != NULL;
		wContact = CallService(MS_DB_CONTACT_FINDNEXT, wContact, 0))
	{
		OnCListApplyIcons(wContact, 0);
	}
}

/**
 * name:	EnableExtraIcons
 * desc:	reload the module
 * params:	bEnable	- determines whether icons are enabled or not
 * return:	0
 **/
VOID EnableExtraIcons(BOOLEAN bEnable, BOOLEAN bUpdateDB) 
{
	static HANDLE	hChangedHook = 0,
					hApplyIconHook = 0,
					hRebuildIconsHook = 0;

	if(!myGlobals.HaveCListExtraIcons)
		return;

	if(bUpdateDB)
		DBWriteContactSettingByte(NULL, MODNAME, SET_CLIST_EXTRAICON_HOMEPAGE, bEnable);

	if(bEnable) {
		// hook events
		if(hChangedHook == NULL) hChangedHook = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged);
		if(hApplyIconHook == NULL) hApplyIconHook = HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY, OnCListApplyIcons);
		if(hRebuildIconsHook == NULL) hRebuildIconsHook = HookEvent(ME_CLIST_EXTRA_LIST_REBUILD, OnCListRebuildIcons);

		OnCListRebuildIcons(0, 0);
	}
	else {
		UnhookEvent(hChangedHook); hChangedHook = NULL;
		UnhookEvent(hApplyIconHook); hApplyIconHook = NULL;
		UnhookEvent(hRebuildIconsHook); hRebuildIconsHook = NULL;
	}
	ApplyCListIcons();
}

/**
 * name:	OnModulesLoaded
 * desc:	initiate the module
 * params:	none
 * return:	0
 **/
VOID OnModulesLoaded()
{
	CreateServiceFunction(MS_USERINFO_HOMEPAGE_OPENURL, MenuCommand);
	EnableExtraIcons(DBGetByte(SET_CLIST_EXTRAICON_HOMEPAGE, DEFVAL_CLIST_EXTRAICON_HOMEPAGE), FALSE);
}

} // namespace NViewHomepage
} // namespace NServices
